package com.yunbiao.ybbusstopplate.serialport

import android.app.Service
import android.content.Intent
import android.os.Environment
import android.os.Handler
import android.os.IBinder
import android.os.Looper
import android.os.Message
import android.util.Log
import com.blankj.utilcode.util.FileIOUtils
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.ThreadUtils
import com.blankj.utilcode.util.ThreadUtils.SimpleTask
import com.blankj.utilcode.util.ToastUtils
import com.yunbiao.ybbusstopplate.bean.SiteInfoBean
import com.yunbiao.ybbusstopplate.refactoring.ui.yibin.ZHXPortAgreement
import com.yunbiao.ybbusstopplate.refactoring.utils.Utils
import com.yunbiao.ybbusstopplate.serialport.agreement.AgreementTool
import com.yunbiao.ybbusstopplate.serialport.agreement.IAgreementListener
import com.yunbiao.ybbusstopplate.ui.dialog.LetterErrorDialogTool
import com.yunbiao.ybbusstopplate.utils.BytesUtils
import com.yunbiao.ybbusstopplate.utils.SpTool
import com.yunbiao.ybbusstopplate.utils.eventbus.EventMsgTool
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import tp.xmaihh.serialport.SerialHelper
import tp.xmaihh.serialport.bean.ComBean
import tp.xmaihh.serialport.stick.AbsStickPackageHelper
import java.io.File
import java.io.IOException
import java.io.InputStream
import kotlin.concurrent.thread

class SerialPortService2 :Service() {
    val TAG="SerialPortService2"
    var iAgreementListener: IAgreementListener?=null
    var serialHelper:SerialHelper?=null

    val code_agreement_error=1
    val code_open_error=2

    var handler:Handler= Handler(Looper.getMainLooper(),object :Handler.Callback{
        override fun handleMessage(p0: Message): Boolean {
            when(p0.what){
                code_agreement_error->{
                    ToastUtils.showShort("解析失败，请联系管理员！！！")
                    LetterErrorDialogTool.showLetterErrorDialog()
                }
                code_open_error->{
                    LetterErrorDialogTool.showLetterErrorDialog("打开串口失败")
                }
            }
            return false
        }
    })

    override fun onCreate() {
        super.onCreate()
        Log.d(TAG,"onCreate-------------")

        EventBus.getDefault().register(this)
    }

    @Subscribe
    fun onUpdate(o: Any){
        if (o is ZHXPortAgreement) {

            ThreadUtils.executeByCached<Any>(object : SimpleTask<Any?>() {
                @Throws(Throwable::class)
                override fun doInBackground(): Any {
                    val file = File(Environment.getExternalStorageDirectory(), "test222.txt")
                    val strings = FileIOUtils.readFile2List(file)
                    for (string in strings) {
                        if (string.contains("<---")) {
                            val split = string.split("<---".toRegex()).dropLastWhile { it.isEmpty() }
                                .toTypedArray()
                            val s = split[1]
                            Log.d(TAG,"onUpdate: $s")
                            val bytes = Utils.hexToByteArray(s)
                            AgreementTool.analysisData(serialHelper!!,bytes,iAgreementListener)

                            Thread.sleep(20);
                        }
                    }
                    return 1
                }

                override fun onSuccess(p0: Any?) {
                    Log.d(TAG, "onSuccess: ")
                }
            })
        }
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        thread{
            Log.d(TAG,"onStartCommand-------------")
            initListener()
            initSerialHelper()
            openSerial()
        }
        return super.onStartCommand(intent, flags, startId)
    }

    override fun onBind(p0: Intent?): IBinder? {
        return null
    }

    override fun onDestroy() {
//        iAgreementListener=null
        closeSerial()
        LetterErrorDialogTool.dismissLetterErrorDialog()
        super.onDestroy()
        Log.d(TAG,"onDestroy-------------")
    }

    private fun initListener(){
        //数据解析监听
        iAgreementListener=object :IAgreementListener{
            //站点列表
            override fun onSiteListResult(list: ArrayList<String>) {
//                for (ss in list){
//                    System.out.println(ss)
//                }
                Log.d(TAG, "onSiteListResult: $list")
                val list1 = arrayListOf<String>()
                list1.clear()
//                list1.addAll(list.take(9) )
                list1.addAll(list )
                EventMsgTool.getInstance().postSiteList(list1)
            }
            //到站、离站显示屏信息
            override fun onSiteTipResult(siteInfoBean: SiteInfoBean) {
//                System.out.println("tip->"+siteInfoBean.tip+" ,time->"+siteInfoBean.time)
                EventMsgTool.getInstance().postSiteTip(siteInfoBean)
            }
            //当前线路名[0]、始发[1]、终点站[2]
            override fun onLineInfoResult(lineInfoArray: Array<String>) {
                EventMsgTool.getInstance().postLineInfo(lineInfoArray)
            }

            //首末班时间
            override fun onSiteTimeResult(s1: String, e1: String, s2: String, e2: String) {
                var data = arrayOf(s1,e1,s2,e2)
                EventMsgTool.getInstance().postSiteTime(data)
            }

            //解析失败
            override fun agreementFailed() {
//                ToastUtils.showShort("解析失败，请联系管理员！！！")
//                LetterErrorDialogTool.showLetterErrorDialog()

                handler.sendEmptyMessage(code_agreement_error)
            }
        }
    }

    private fun initSerialHelper(){
        //获取设置的port
        val portType = SpTool.getConfigSerialPortType()

        if (portType==-1){
            Log.e(TAG, "initSerialHelper: 打开串口失败。")
            handler.sendEmptyMessage(code_open_error)
            return
        }
        //初始化portType
        SerialPortConfig.init(portType)

        LogUtils.getConfig().isLog2FileSwitch = SpTool.getLogToFile()
        LogUtils.getConfig().setDir(File(Environment.getExternalStorageDirectory(), "bus_log"))

        serialHelper=object :SerialHelper(SerialPortConfig.UART_PATH,SerialPortConfig.BAUDRATE){
            override fun open() {
                super.open()
                var result = if(isOpen) "成功" else "失败"
                LogUtils.d(TAG,"打开串口：" + SerialPortConfig.UART_PATH + ",波特率：" + SerialPortConfig.BAUDRATE + "," + result)
            }

            override fun close() {
                super.close()
                LogUtils.d(TAG,"关闭串口")
            }

            override fun onDataReceived(paramComBean: ComBean?) {
                val bRec = paramComBean!!.bRec
                if (bRec != null) {
                    val bytesToHex = BytesUtils.bytesToHex(bRec)
//                    Log.e(TAG, "HEX---->$bytesToHex")
                    LogUtils.d(TAG, "<---$bytesToHex")

                    AgreementTool.analysisData(serialHelper!!,bRec,iAgreementListener)
                }
            }

            override fun sendHex(sHex: String?) {
                LogUtils.d(TAG,"--->$sHex")
                super.sendHex(sHex)
            }
        }
        serialHelper!!.setStickPackageHelper(object : AbsStickPackageHelper{
            override fun execute(`is`: InputStream?): ByteArray {
                val bytes = ByteArray(512)
                try {
                    val size: Int = `is`!!.read(bytes)
                    if (size > 0) {
                        return BytesUtils.SubByte(bytes, 0, size)
                    }
                } catch (e: IOException) {
                    e.printStackTrace()
                }
                return bytes
            }
        })
    }

    private fun openSerial() {
        if (serialHelper != null) {
            try {
                serialHelper!!.open()
                Log.d(TAG,"openSerial: 打开串口成功")
            } catch (e: java.lang.Exception) {
                Log.e(TAG, "openSerial: 打开串口失败。")
                handler.sendEmptyMessage(code_open_error)
                e.printStackTrace()
            }
        }
    }

    private fun closeSerial() {
        if (serialHelper != null) {
            try {
                serialHelper!!.close()
                serialHelper==null
            } catch (e: java.lang.Exception) {
                Log.e(TAG, "closeSerial: 关闭串口失败。")
                e.printStackTrace()
            }
        }
    }
}